package com.yale.elasticsearch.service.query;

import com.yale.elasticsearch.dto.MatchQueryDTO;
import com.yale.elasticsearch.model.entity.UserInfo;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.query_dsl.*;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.json.JsonData;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 匹配查询
 */
@Slf4j
@Service
public class MatchQueryService {

    @Resource
    private ElasticsearchClient elasticsearchClient;

    /**
     * 匹配查询符合条件的所有数据，并设置分页
     */
    public Object matchAllQuery(MatchQueryDTO matchQueryDTO) {
        Object result = "";
        try {

            // 创建查询请求对象
            SearchRequest searchRequest = SearchRequest.of(s -> s
                    .index(matchQueryDTO.getIndexName())
                    .query(Query.of(q -> q
                            .matchAll(MatchAllQuery.of(m -> m))
                    ))
                    .from(0)  // 设置分页的起始位置
                    .size(3)  // 设置每页的大小
                    .sort(sort -> sort
                            .field(f -> f
                                    .field(matchQueryDTO.getField())
                                    .order(matchQueryDTO.getSort() == 1? SortOrder.Asc : SortOrder.Desc)  // 使用 SortOptions.Order.Asc 来指定升序
                            )
                    )
            );

            // 执行查询
            SearchResponse<JsonData> searchResponse = elasticsearchClient.search(searchRequest, JsonData.class);

            // 处理响应结果
            if (searchResponse.hits().total().value() > 0) {
                searchResponse.hits().hits().forEach(hit -> {
                    // 将 JSON 转换成对象
                    UserInfo userInfo = JSON.parseObject(hit.source().toJson().toString(), UserInfo.class);
                    // 输出查询信息
                   log.info("打印结果：{}",JSON.toJSONString(userInfo));
                });
            }

            result = JSON.toJSONString(searchResponse.hits().hits());

        } catch (IOException e) {
           log.error("Error executing search request: {}" , e.getMessage());
        }
        return result;
    }


    /**
     * 匹配查询数据
     */
    public Object matchQuery(MatchQueryDTO matchQueryDTO) {
        Object result = "";
        try {
            // 构建 Match 查询条件
            MatchQuery matchQuery = new MatchQuery.Builder()
                    .field(matchQueryDTO.getField())
                    .query(matchQueryDTO.getValue())
                    .build();

            // 创建查询请求对象
            SearchRequest searchRequest = SearchRequest.of(s -> s
                    .index(matchQueryDTO.getIndexName())
                    .query(Query.of(q -> q
                            .match(matchQuery)
                    ))
            );

            // 执行查询
            SearchResponse<JsonData> searchResponse = elasticsearchClient.search(searchRequest, JsonData.class);
            List<UserInfo> userInfoList = new ArrayList<>();
            // 处理响应结果
            if (searchResponse.hits().total().value() > 0) {
                searchResponse.hits().hits().forEach(hit -> {
                    // 将 JSON 转换成对象
                    UserInfo userInfo = JSON.parseObject(hit.source().toString(), UserInfo.class);
                    userInfoList.add(userInfo);
                    // 输出查询信息
                    log.info("打印结果：{}",JSON.toJSONString(userInfo));
                });
            }

            result = JSON.toJSONString(userInfoList);

        } catch (IOException e) {
            log.error("Error executing search request: {}" , e.getMessage());
        }
        return result;
    }


    /**
     * 词语匹配查询
     */
    public Object matchPhraseQuery(MatchQueryDTO matchQueryDTO) {
        Object result = "";
        try {
            // 构建 Match Phrase 查询条件
            MatchPhraseQuery matchPhraseQuery = new MatchPhraseQuery.Builder()
                    .field(matchQueryDTO.getField())
                    .query(matchQueryDTO.getValue())
                    .build();

            // 创建查询请求对象
            SearchRequest searchRequest = SearchRequest.of(s -> s
                    .index(matchQueryDTO.getIndexName())
                    .query(Query.of(q -> q
                            .matchPhrase(matchPhraseQuery)
                    ))
            );

            // 执行查询
            SearchResponse<JsonData> searchResponse = elasticsearchClient.search(searchRequest, JsonData.class);
            List<UserInfo> userInfoList = new ArrayList<>();
            // 处理响应结果
            if (searchResponse.hits().total().value() > 0) {
                searchResponse.hits().hits().forEach(hit -> {
                    // 将 JSON 转换成对象
                    UserInfo userInfo = JSON.parseObject(hit.source().toString(), UserInfo.class);
                    userInfoList.add(userInfo);
                    // 输出查询信息
                   log.info("打印结果：{}",JSON.toJSONString(userInfo));
                });
            }

            result = JSON.toJSONString(userInfoList);

        } catch (IOException e) {
            log.error("Error executing search request: {}" , e.getMessage());
        }
        return result;
    }


    /**
     * 内容在多字段中进行查询
     */
    public Object matchMultiQuery(MatchQueryDTO matchQueryDTO) {
        Object result = "";
        try {
            List<String> fieldList = new ArrayList<>();
            if(matchQueryDTO.getFields() != null){
                fieldList = Arrays.asList(matchQueryDTO.getFields());
            }
            // 构建 Multi Match 查询条件
            MultiMatchQuery multiMatchQuery = new MultiMatchQuery.Builder()
                    .fields(fieldList)
                    .query(matchQueryDTO.getValue())
                    .build();

            // 创建查询请求对象
            SearchRequest searchRequest = SearchRequest.of(s -> s
                    .index(matchQueryDTO.getIndexName())
                    .query(q -> q
                            .multiMatch(multiMatchQuery)
                    )
            );

            // 执行查询
            SearchResponse<JsonData> searchResponse = elasticsearchClient.search(searchRequest, JsonData.class);
            List<UserInfo> userInfoList = new ArrayList<>();
            // 处理响应结果
            if (searchResponse.hits().total().value() > 0) {
                searchResponse.hits().hits().forEach(hit -> {
                    // 将 JSON 转换成对象
                    UserInfo userInfo = JSON.parseObject(hit.source().toString(), UserInfo.class);
                    userInfoList.add(userInfo);
                    // 输出查询信息
                   log.info("打印结果：{}",JSON.toJSONString(userInfo));
                });
            }

            result = JSON.toJSONString(userInfoList);

        } catch (IOException e) {
            log.error("Error executing search request: {}" , e.getMessage());
        }
        return result;
    }


}
